﻿

namespace BlazorAppAuth.Plc
{
    using S7.Net;
    public class PlcMgr
    {
        private readonly string _plcIpAddress;
        private readonly short _plcRack;
        private readonly short _plcSlot;
        private Plc _plc;


        public PlcMgr(string plcIpAddress, short plcRack, short plcSlot)
        {
            _plcIpAddress = plcIpAddress;
            _plcRack = plcRack;
            _plcSlot = plcSlot;
            _plc = new Plc(CpuType.S71500, _plcIpAddress, _plcRack, _plcSlot);
        }

        public async Task<bool> ConnectAsync()
        {
            try
            {
                await _plc.OpenAsync();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task DisconnectAsync()
        {
            _plc.Close();
        }

        //public async Task<T> ReadDataAsync<T>(string address)
        //{
        //    //return await _plc.ReadAsync(address);
        //}

        public async Task WriteDataAsync<T>(string address, T value)
        {
            await _plc.WriteAsync(address, value);
        }

        public async Task<bool> IsConnectedAsync()
        {
            return await Task.FromResult(_plc.IsConnected);
        }
        private T ConvertToType<T>(object value)
        {
            if (typeof(T) == typeof(bool))
            {
                return (T)(object)((bool)value);
            }
            else if (typeof(T) == typeof(short))
            {
                return (T)(object)((ushort)value).ConvertToShort();
            }
            else if (typeof(T) == typeof(int))
            {
                return (T)(object)((uint)value).ConvertToInt();
            }
            else if (typeof(T) == typeof(float))
            {
                return (T)(object)((uint)value).ConvertToFloat();
            }
            else if (typeof(T) == typeof(double))
            {
                // For double, we first convert to float, then to double
                float floatValue = ((uint)value).ConvertToFloat();
                return (T)(object)(double)floatValue;
            }
            else if (typeof(T) == typeof(string))
            {
                // For string, we need to handle it differently
                if (value is byte[] bytes)
                {
                    // Assuming the string is stored as UTF-8
                    return (T)(object)System.Text.Encoding.UTF8.GetString(bytes).TrimEnd('\0');
                }
                else
                {
                    throw new ArgumentException("Expected byte array for string conversion");
                }
            }
            else
            {
                throw new NotSupportedException($"Type {typeof(T)} is not supported for conversion.");
            }
        }
    }
}
